package org.computate.controller.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.computate.model.dao.ComputateDao;
import org.computate.model.item.Model;
import org.computate.tool.ModelTool;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.google.inject.Inject;
import com.google.inject.Singleton;


@Singleton
public class JsonItemFilter extends HttpServlet implements Filter {
	
	@Inject private ModelTool modelTool;
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 5289872871843461740L;

	@Override
	public void destroy() {
	}
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		servlet(request, response);
		//super.doGet(request, response);
	}
	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		servlet(request, response);
		//super.doPost(request, response);
	}
	
	private void servlet(HttpServletRequest request, HttpServletResponse response) {
		String requestURI = request.getRequestURI();
		
		response.setContentType("application/json");
		try {
			if(StringUtils.endsWith(requestURI, "index.json")) {
				String modelName = StringUtils.substringAfterLast(StringUtils.substringBeforeLast(requestURI, "index.json"), "/");
				List<? extends Model> items = index(request, response, modelName);
				
				filterIndex(request, response, items);
			}
			else if(StringUtils.endsWith(requestURI, "edit.json")) {
				Model item = edit(request, response);
				
				filterEdit(request, response, item);
			}
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}	
	
	public List<? extends Model> index(HttpServletRequest request, HttpServletResponse response, String modelName) throws InstantiationException, IllegalAccessException {
		Class<?> itemClass = modelTool.getItemClass(modelName);
		List<? extends Model> items = new ArrayList<Model>();
		
		if(itemClass != null) {
			ComputateDao<?> dao = modelTool.getDao(modelName);
			Model newInstance = (Model)itemClass.newInstance();
			
			items = dao.list(newInstance.getListLevels());
			request.setAttribute("modelName", modelName);
			request.setAttribute("modelDisplayName", newInstance.getModelDisplayName());
			request.setAttribute("modelPluralName", newInstance.getModelPluralName());
			request.setAttribute("items", items);
		}
		
		return items;
	}
	
	public Model edit(HttpServletRequest request, HttpServletResponse response) throws InstantiationException, IllegalAccessException {
		String modelName = request.getParameter("model");
		String fieldName = request.getParameter("field");
		String idParam = request.getParameter("id");
		Long id = NumberUtils.toLong(idParam);
		String valueParam = request.getParameter("update_value");
		Class<? extends Model> c = modelTool.getClass(modelName);
		Model newInstance = (Model)c.newInstance();
		ComputateDao<?> dao = modelTool.getDao(modelName);
		Model item = modelTool.getItem(dao, id, newInstance.getGetLevels());
		//ObjectMapper jsonMapper = new ObjectMapper();
		
		modelTool.edit(fieldName, c, item, valueParam, dao);
		
		try {
			ServletOutputStream outputStream = response.getOutputStream();
			//jsonMapper.writeValue(outputStream, valueParam);
			IOUtils.write(valueParam, outputStream);
		} catch (JsonGenerationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JsonMappingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return item;
	}
	
	public Model view(HttpServletRequest request, HttpServletResponse response, String modelName) throws InstantiationException, IllegalAccessException {
		return null;
	}
	
	public Model delete(HttpServletRequest request, HttpServletResponse response, String modelName) throws InstantiationException, IllegalAccessException {
		ComputateDao<?> dao = modelTool.getDao(modelName);
		String idParam = request.getParameter("id");
		Long id = NumberUtils.toLong(idParam);
		Model item = dao.delete(id);
		
		request.setAttribute("modelName", modelName);
		request.setAttribute("item", item);
		
		return item;
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
	}

	protected void filterIndex(HttpServletRequest request, HttpServletResponse response, List<? extends Model> itemObjects) {
		
	}
	
	protected void filterEdit(HttpServletRequest request, HttpServletResponse response, Model itemObject) {
		
	}
	
	protected void filterView(HttpServletRequest request, HttpServletResponse response, Model itemObject) {
		
	}
	
	protected void filterDelete(HttpServletRequest request, HttpServletResponse response, Model itemObject) {
		
	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1,
			FilterChain arg2) throws IOException, ServletException {
		// TODO Auto-generated method stub
		
	}
	
//	private void filterEdit(HttpServletRequest request, HttpServletResponse response, Model itemObject) {
//		
//	}
}
